package edu.utn.tacs.grupouno.negocio;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import edu.utn.tacs.grupouno.dao.PersistentObject;
import edu.utn.tacs.grupouno.exception.SystemException;

@XmlRootElement
@Entity
public class Analisis extends PersistentObject implements Cloneable {
//dozer. hibernate 4 gwt
	private static final long serialVersionUID = 6462074113940985130L;

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@XmlElementWrapper(name = "estudios")
	@XmlElement(name = "estudio")
	protected List<Estudio> estudios;

	@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
	private Medico medico;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Paciente paciente;

	public Analisis() {
		estudios = new LinkedList<Estudio>();
	}

	public Paciente getPaciente() {
		return paciente;
	}

	public void setPaciente(Paciente paciente) {
		this.paciente = paciente;
	}

	public Medico getMedico() {
		return medico;
	}

	public void setMedico(Medico medico) {
		this.medico = medico;
	}

	@XmlTransient
	public List<Estudio> getEstudios() {
		return estudios;
	}

	public void setEstudios(List<Estudio> estudios) {
		this.estudios = estudios;
	}

	public void addEstudio(Estudio estudio) {
		estudios.add(estudio);
	}

	public void addEstudios(Collection<Estudio> estudios) {
		this.estudios.addAll(estudios);
	}

	public void deleteEstudios() {
		estudios.clear();
	}

	public void deleteEstudio(UUID id) {
		for (Estudio estudio : estudios) {
			if (estudio.getId().equals(id)) {
				estudios.remove(estudio);
				return;
			}
		}
	}
	
	/**
	 * 
	 * @return una coleccion de estudios que poseen todos sus indicadores cargados,
	 * es decir que cada uno de los indicadores posee un resultado asignado
	 */
	public List<Estudio> getEstudiosConIndicadoresCargados() {
		List<Estudio> estudiosCargados = new LinkedList<Estudio>();
		
		for (Estudio estudio : estudios) {
			if (estudio.seCargaronTodosLosIndicadores()) {
				estudiosCargados.add(estudio);
			}
		}
		
		return estudiosCargados;
	}

	public boolean isListo(){
		for(Estudio estudio: estudios){
			if(!estudio.seCargaronTodosLosIndicadores()) {
				return false;
			}
		}
		return true;
	}

	public void notificarMedico(){
		if (isListo()){
			medico.analisisTerminado(this);
		}
	}

	@Override
	public Analisis clone(){
		Analisis analisisClon;
		try {
			analisisClon = (Analisis) super.clone();
			analisisClon.setEstudios(new LinkedList<Estudio>());
			analisisClon.setId(UUID.randomUUID());
			
			for (Estudio estudio : this.getEstudios()){
				analisisClon.addEstudio((Estudio) estudio.clone());
			}
		}
		catch (CloneNotSupportedException e) {
			throw new SystemException("No se pudo clonar analisis!");
		}
		return analisisClon;
	}

}